home *** CD-ROM | disk | FTP | other *** search
- page ,132
- .model large, basic
- .286
- comment |
- This routine can help you maintain currency variables to a fixed
- number of decimal places. This is the VB version of the code.
-
- ----------------------------------------------------------------------
- Written by Jim Mack, CIS 76630,2012, bix "jsmack"
- Copyright 1991, Editing Services Co. All rights reserved.
-
- Free for non-commercial use: commercial rights freely granted on
- written request, with acknowledgement of copyright.
- ----------------------------------------------------------------------
-
- DECLARE SUB CurrFix lib "currfix.dll" (CurrVal@, ByVal Places%, ByVal Truncate%)
- Adjusts the passed Currency variable (if required) to remove one
- or more digits to the right of the decimal point.
-
- CurrVal@ is directly modified, not returned as a function result.
-
- Places% may be 0 to 3 and will result in a value with the indicated
- number of digits beyond the decimal point. Other values are ingored
- with CurrVal@ left unchanged.
-
- If Truncate% is non-zero the excess places are simply removed,
- otherwise the value is rounded using traditional financial rounding.
-
- Performs the equivalent of the following Basic code:
-
- CVal@ = INT((CVal@ * (10^n)) + .5) / (10^n)
-
- Floating point is avoided for maximum speed.
- ----------------------------------------------------------------------
- |
-
- by equ <byte ptr> ;; convenient shorthand macros
- wo equ <word ptr>
- bit equ <1 shl>
-
- EPNegate MACRO MemArg ;; extended-precision integer unary negate
-
- xor ax, ax
- neg wo MemArg
- not wo MemArg+2
- not wo MemArg+4
- not wo MemArg+6
- cmc
- adc MemArg+2, ax
- adc MemArg+4, ax
- adc MemArg+6, ax
-
- ENDM
- ;---------------------------------------------------------------------------
-
- .code
-
- PTable dw 10000, 1000, 100, 10
-
- CurrFix PROC uses di si, currval:dword, places, truncate
- LOCAL sgn
-
- lds si, currval ; --> currency value
- mov sgn, 0
- test by 7[si], bit 7 ; negative?
- jz @f
- dec sgn ; yes, indicate for exit
- EPNegate [si] ; and make positive (negate -number)
- @@:
- mov bx, places
- cmp bx, 0
- jl cferr
- cmp bx, 3
- jna @f ; all OK
-
- cferr: jmp cfx90 ; ignore if > 3 or < 0
-
- @@: add bx, bx
- mov cx, PTable[bx]
- mov ax, 6[si]
- xor dx, dx
- div cx
- mov 6[si], ax
- mov ax, 4[si]
- div cx
- mov 4[si], ax
- mov ax, 2[si]
- div cx
- mov 2[si], ax
- mov ax, [si]
- div cx
- mov [si], ax ; value MOD [CX] in DX now
- shr cx, 1
- xor ax, ax
- cmp truncate, ax ; round or truncate?
- jne @f ; truncate: skip next test
- cmp dx, cx ; clear carry if remainder >= half
- jc @f
- cmc
- adc [si], ax
- adc 2[si], ax
- adc 4[si], ax
- adc 6[si], ax
- ;
- ; Multiplying will restore zeroes to the last places
- ;
- @@:
- shl cx, 1 ; restore divisor as multiplier
- mov ax, [si]
- mul cx
- mov di, dx ; accumulate partial product
- mov [si], ax
- mov ax, 2[si]
- mul cx
- mov bx, dx
- mov 2[si], ax
- mov ax, 4[si]
- mul cx
- push dx
- mov 4[si], ax
- mov ax, 6[si]
- mul cx
- mov 6[si], ax
- pop dx
- add 2[si], di ; shifted partial product in DX:BX:DI
- adc 4[si], bx
- adc 6[si], dx
- cmp sgn, 0 ; was negative?
- je cfx90
- EPNegate [si] ; if so, make negative again
- cfx90:
- ret
-
- CurrFix ENDP
-
- END
-